跳到主要内容

05-高可用篇-2

哨兵机制

为什么要有哨兵机制

Redis 的主从结构是读写分离的,如果主节点挂了,则无法处理客户端的写操作请求,也无法跟从节点进行数据同步
此时如果要恢复服务,需要人工介入将一个从节点切换为主节点,并让其他从节点执行新的主节点,同时还要通知上游连接 Redis 主节点的客户端更新主节点的地址
Redis 在 2.8 版本后提供 哨兵(Sentinel)机制,作用是实现 主从节点故障转移,它会对检测主节点是否存活,如果主节点挂了,就会选举一个从节点切换为主节点,并且将新主节点的相关信息通知给从节点和客户端

哨兵集群如何工作

哨兵其实是一个运行在特殊模式下的 Redis 进程,也是一个节点,相当于观察者节点,观察对象是主从节点,主要负责三件事情:监控、选主、通知

如何判断主节点故障

  • 哨兵每隔 1S 给所有主从节点发送 PING 命令,当主从节点收到命令后会发送一个响应命令给哨兵,这样就可以判断主从节点是否正常运行
  • 如果节点没有在规定时间内响应哨兵的 PING 命令,哨兵就会将他们标记为主观下线,这个规定时间 由配置项down-after-milliseconds 设置,单位是毫秒
    判断节点运行
  • 客观下线
    客观下线只适用于主节点,针对主节点设计主观下线客观下线,是因为主节点有可能并没有故障,只是因为系统压力较大 或者网络拥塞 导致主节点没有在规定时间内发送响应命令
    因此为了减少误判,哨兵在部署是不会只部署一个节点,而是多个节点组成哨兵集群(至少三台),通过多个哨兵一起判断,可以避免单个哨兵因为自身网络状况不好导致误判主节点下线的的情况
  • 如何判断客观下线
    当一个哨兵判断主节点为主观下线后,会向其他哨兵发起命令,其他哨兵收到命令后会根据自身和主节点之间的网络状况做出赞成投票或者拒绝投票的响应
    判断客观下线
    当投票的赞成票数达到哨兵配置文件中 quorum 配置项设定的值后,主节点就会被该哨兵标记为客观下线
    quorum 的值一般设置为哨兵个数的 1/2 + 1
    哨兵在判断完主节点客观下线后,就要开始在多个从节点中选出一个来做新主节点

由哪个哨兵进行主从故障转移

  • 哨兵以集群方式存在,因此还需要在哨兵集群中选出一个 leader,让 leader 来执行主从切换

  • 哪个哨兵节点判断主节点为客观下线,它就是 leader 的候选者

  • leader 的候选者

  • 如何选举
    候选者会向其他哨兵发送命令,表明希望成为 leader 来执行主从切换,并让其他节点进行投票每个哨兵只有一次投票机会,可以投给自己或者其他哨兵,但是只有候选者能投给自己投票过程中任何一个候选者要满足两个条件才能选举成功:

    1. 拿到半数以上的赞成票
    2. 拿到的票数需要大于等于哨兵配置文件中的 quorum 值

    如果没有满足条件,则需要重新进行选举

  • 哨兵想要成功竞选 Leader 需要获得 哨兵个数的 1/2 + 1 票,如果集群只有两个节点,挂掉一个节点后无论如何都无法选举成功,无法进行主从切换,因此通常至少配置三个哨兵节点,即使挂掉一个节点也有可能选举成功
    哨兵节点的数量应该是奇数

主从节点故障转移的过程

  • 哨兵集群通过投票的方式选出 leader 之后就可以进行主从故障转移的过程
    主从故障转移
    1. 在已下线主节点属下的所有从节点中挑选一个从节点,将其转换为主节点
    2. 让已下线主节点属下的所有从节点修改复制目标为新主节点
    3. 将新主节点的 IP 地址和信息通过 订阅/发布机制 通知给客户端
    4. 继续监视旧主节点,当它重新上线时将它设置为新主节点的从节点

步骤一:选出新主节点

  • 故障转移第一步就是在已下线主节点的所有从节点中选出一个状态良好、数据完整的从节点,然后向这个从节点发送 SLAVEOF no noe 命令,将其转换为主节点

  • 如何选择可以作为主节点的从节点
    选主过程

    • 过滤网络不好的从节点
      首先要把网络不好的从节点过滤掉,包括 已经下线的从节点以往网络连接状态不好的节点
      Redis 中的配置项 down-after-milliseconds * 10 表示主从节点断连的最大连接超时时间,如果在这个时间内主从节点没有连接上,就可以认为主从节点断连,如果断连次数超过 10 次,就可以认为这个从节点网络状况不好,不适合作为新主节点
    • 三轮考察
      把网络不好的从节点过滤掉之后,要对剩下的所有从节点进行三轮考察,分别是:优先级、复制进度、ID
      • 第一轮考察:优先级最高的从节点
        哨兵会根据从节点的优先级进行排序,优先级越高排名越靠前,Redis 中的配置项 slave-priority 用于设置从节点优先级,每一台从节点的配置不一定是相同的,可以根据性能来设置从节点的优先级
        如果第一轮考察中有多个节点胜出,就会进行第二轮考察
      • 第二轮考察:复制进度最靠前的从节点
        主从架构中主节点使用 master_repl_offset 记录当前最新写操作在 repl_backing_buffer 中的位置,从节点会使用 salve_repl_offset 记录当前复制进度,选取进度最接近 master_repl_offset 的节点最为新主节点
        如果第二轮考察中有多个节点胜出,就会进行第三轮考察
      • 第三轮考察:ID 号小的从节点胜出
        每个从节点都有一个唯一的 ID 号用于唯一标识从节点,ID 号最小的从节点胜出作为新主节点
  • 选举完成后,哨兵 leader 向被选中从节点发送 SLAVEOF no one 命令,让这个从节点接触从节点的身份,变成新主节点
    解除从节点
    在发送 SLAVEOF no one 之后,哨兵 leader 会以 1S/次 的频率向被升级的从节点发送 INFO 命令(未进行故障转移前是 10S/次 ),并观察命令中回复的角色信息,当节点的角色信息从 salve 变成 master 时,意味着节点已经顺利升级为主节点
    顺利升级

步骤二:将从节点指向新主节点

当新主节点出现后,哨兵 leader 下一步要做的就是让已下线主节点的所有从节点指向新主节点,通过向从节点发送 SLAVEOF 实现
发送 SLAVEOF
指向新主节点

步骤三:通知客户端更换主节点

哨兵集群完成主从切换后,通过 Redis 的 订阅发布机制 将新主节点的信息通知给客户端,每个哨兵节点提供 订阅发布机制,客户端从哨兵订阅消息
客户端与哨兵建立联系后,会订阅哨兵提供的频道,主从切换完成后哨兵就会向 +switch-master 频道发布新主节点的 IP 地址和端口消息,客户端接收到消息后使用新的 IP 和 端口和新主节点进行通信
客户端不仅可以在主从切换后获得新主节点的连接信息,也可以监控主从切换过程中发生的各种重要事件,了解切换进度
常见事件
常见事件

步骤四:将旧主节点变为从节点

完成主从切换后继续监视旧主节点,当重新上线时,哨兵集群就会向它发送 SLAVEOF 命令,使其成为新主节点的从节点,到这一步主从节点的故障转移工作结束
旧主节点->从节点

哨兵集群如何组成

哨兵集群的组成方式也使用了订阅发布机制,在主从集群上,主节点提供了一个名为 __sentinel__:hello 的通道,哨兵通过他来互相发现,实现互相通信
哨兵互相发现

哨兵如何获取从节点信息

主节点知道所有从节点的信息,因此哨兵会 10S/次 向主节点发送 INFO 命令获取所有从节点信息,然后就可以根据主节点发送的从节点列表中的连接信息,和每个从节点建立连接,并在这个连接上持续的对从节点进行监控
连接从节点